package edu.yourl.presenter;

import java.util.Calendar;
import java.util.Map;
import java.util.TreeMap;

import org.springframework.transaction.annotation.Transactional;

import edu.yourl.domain.Domain;
import edu.yourl.domain.FavoritableVisitor;
import edu.yourl.domain.Gossip;
import edu.yourl.domain.Gossiper;
import edu.yourl.domain.Url;
import edu.yourl.domain.User;
import edu.yourl.persistence.IGossipRepository;
import edu.yourl.persistence.IUserRepository;
import edu.yourl.web.components.IGossipView;

public class GossipPresenter implements IGossipPresenter {

	private IUserRepository userRepository;
	private IGossipRepository gossipRepository;

	public void renderGossip(Gossip gossip, final IGossipView view) {
		view.clear();
		String msg = gossip.getMessage();
		Map<Integer, Gossiper> positions = new TreeMap<Integer, Gossiper>();
		
		// Primero obtenemos todas las posiciones donde aparecen las cosas que queremos linkear
		for (Gossiper gossiper : gossip.getTo()) {
			int currentPosition = 0;
			while ((currentPosition = msg.indexOf(gossiper.getFavoritableName(), currentPosition)) != -1) {			
				positions.put(currentPosition, gossiper);
				currentPosition += gossiper.getFavoritableName().length();
			}
		}
		
		// Despues las recorremos ordenadas
		int currentPosition = 0;
	
		FavoritableVisitor<Void> visitor = new FavoritableVisitor<Void>() {

			@Override
			public Void visit(Domain domain) {
				// Esto no pasa, el gossip solo apunta a urls y usuarios
				return null;
			}

			@Override
			public Void visit(Url url) {
				view.addUrl(url);
				return null;
			}

			@Override
			public Void visit(User user) {
				view.addUser(user);
				return null;
			}
		};
		
		for(Integer nextPosition : positions.keySet()) {
			view.addText(msg.substring(currentPosition, nextPosition));
			Gossiper gossiper = positions.get(nextPosition);
			gossiper.accept(visitor);
			currentPosition = nextPosition + gossiper.getFavoritableName().length();
		}
		String lastPart = msg.substring(currentPosition);
		if (!lastPart.isEmpty()) {
			view.addText(lastPart);
		}
	}

	@Override
	public String getPrintableDate(Gossip gossip) {
	    
		long diffMillis = Calendar.getInstance().getTimeInMillis() - gossip.getDate().getTime();
	    long diff = diffMillis / (365 * 24 * 60 * 60 * 1000);
	    
	    if (diff > 0) {
	    	return diff + " a&ncute;os";
	    }
	    
	    diff = diffMillis / (30 * 24 * 60 * 60 * 1000);

	    if (diff > 0) {
	    	return diff + " meses";
	    }

	    diff = diffMillis / (24 * 60 * 60 * 1000);

	    if (diff > 0) {
	    	return diff + " dias";
	    }

	    diff = diffMillis / (60 * 60 * 1000);

	    if (diff > 0) {
	    	return diff + " horas";
	    }

	    diff = diffMillis / (60 * 1000);

	    if (diff > 0) {
	    	return diff + " minutos";
	    }
	    
	    return "menos de un minuto";
	}

	@Override
	@Transactional
	public void reportAbuse(IGossipView view) {
		User reporter = userRepository.getUser(view.getCurrentUserNick());
		Gossip gossip = view.getGossip();
		// Necesitamos el gossip que viene de la BD.
		gossip = gossipRepository.get(gossip);
		gossip.reportAbuse(reporter);
		gossipRepository.add(gossip);
	}

	public void setGossipRepository(IGossipRepository gossipRepository) {
		this.gossipRepository = gossipRepository;
	}

	public void setUserRepository(IUserRepository userRepository) {
		this.userRepository = userRepository;
	}

	
}
